7.2.7 Sistema de Archivos
Trabajar con persistencia no es solo leer y escribir contenido: también implica gestionar rutas, carpetas y archivos de forma segura y portable.
En este punto aprenderás a navegar por el sistema de archivos, construir rutas robustas, buscar ficheros por patrón y automatizar tareas comunes sin depender del sistema operativo.
1️⃣ Rutas y portabilidad: el problema real
Un programa puede funcionar en tu equipo y fallar en otro solo por cómo construyes rutas.
Errores típicos:
- Concatenar rutas con
+. - Usar separadores manuales (
\o/). - Escribir rutas absolutas fijas (
C:/...).
🟩 Qué debe cumplir una ruta robusta
- Funcionar en Windows, Linux y macOS.
- No depender del usuario actual.
- Ser legible y fácil de mantener.
🟦 Recomendación general
- Preferir
pathlibpara nuevas implementaciones. - Usar rutas relativas al proyecto o al script.
2️⃣ os vs pathlib
Python ofrece dos enfoques principales.
🟩 Enfoque clásico con os
import os
ruta = os.path.join("data", "logs", "app.log")
print(os.path.exists(ruta))
🟦 Enfoque moderno con pathlib
from pathlib import Path
ruta = Path("data") / "logs" / "app.log"
print(ruta.exists())
🟨 Comparativa (os vs pathlib)
| Criterio | os / os.path | pathlib |
|---|---|---|
| Estilo | Procedimental | Orientado a objetos |
| Legibilidad | Media | Alta |
| Composición de rutas | os.path.join(...) | Operador / |
| Recomendación actual | Compatible | Preferido |
3️⃣ Construcción y resolución de rutas
pathlib permite expresar rutas de forma clara y segura.
🟩 Operaciones básicas
from pathlib import Path
ruta = Path("documentos") / "notas" / "enero.txt"
print(ruta.name) # enero.txt
print(ruta.stem) # enero
print(ruta.suffix) # .txt
print(ruta.parent) # documentos/notas
🟦 Rutas absolutas y normalización
from pathlib import Path
ruta_relativa = Path("data/config.json")
ruta_absoluta = ruta_relativa.resolve()
print(ruta_absoluta)
🟨 Ruta relativa al script
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent
RUTA_DATOS = BASE_DIR / "data" / "db.json"
Este patrón evita errores cuando ejecutas el script desde carpetas distintas.
4️⃣ Operaciones comunes con archivos y carpetas
🟩 Comprobación y creación
from pathlib import Path
carpeta = Path("salidas")
carpeta.mkdir(parents=True, exist_ok=True)
archivo = carpeta / "resultado.txt"
if not archivo.exists():
archivo.touch()
🟦 Lectura y escritura directa con Path
from pathlib import Path
ruta = Path("salidas") / "mensaje.txt"
ruta.write_text("Sistema operativo\n", encoding="utf-8")
contenido = ruta.read_text(encoding="utf-8")
print(contenido)
🟨 Renombrar, mover y borrar
from pathlib import Path
origen = Path("salidas") / "mensaje.txt"
destino = Path("salidas") / "mensaje_final.txt"
origen.rename(destino)
# destino.unlink() # borra archivo
# Path("salidas").rmdir() # borra carpeta vacía
unlink() y rmdir() son acciones destructivas. Valida ruta y contexto antes de ejecutarlas.
5️⃣ Exploración de directorios y búsquedas (glob / rglob)
Buscar ficheros por patrón es una tarea muy habitual (logs, backups, imágenes, etc.).
🟩 Listar contenido inmediato
from pathlib import Path
for elemento in Path(".").iterdir():
print(elemento)
🟦 Filtrar por patrón con glob
from pathlib import Path
for archivo in Path("logs").glob("*.log"):
print(archivo.name)
🟨 Búsqueda recursiva con rglob
from pathlib import Path
for backup in Path(".").rglob("*.bak"):
print(backup)
glob() busca en la carpeta actual. rglob() también entra en subcarpetas.
6️⃣ Rutas relativas vs absolutas (decisión práctica)
🟩 Cuándo usar rutas relativas
- Archivos del propio proyecto.
- Recursos que viajarán con el repositorio.
🟦 Cuándo usar rutas absolutas
- Scripts de administración de sistema.
- Integraciones donde la ubicación está definida externamente.
🟨 Recomendación operativa
En aplicaciones académicas/proyecto: usa rutas relativas al BASE_DIR del script.
Así evitas dependencias del directorio desde el que se lanza el comando.
7️⃣ Ejemplo completo: inspección y limpieza de backups
Aquí se aplica un flujo típico de automatización: localizar archivos por patrón y generar un informe trazable.
from pathlib import Path
base = Path(".")
backup_dir = base / "backups"
backup_dir.mkdir(exist_ok=True)
# 1) localizar backups
backups = list(base.rglob("*.bak"))
# 2) generar informe
informe = base / "informe_backups.txt"
lineas = [f"Total backups encontrados: {len(backups)}\n"]
lineas += [f"- {b}\n" for b in backups]
informe.write_text("".join(lineas), encoding="utf-8")
Flujo recomendado: localizar -> clasificar -> actuar -> registrar resultado.
✅ Buenas prácticas recomendadas
- Usa
pathlibcomo API principal. - Evita rutas absolutas hardcodeadas en código de proyecto.
- Usa
mkdir(..., exist_ok=True)para evitar fallos por carpeta existente. - Usa
encoding="utf-8"al leer/escribir texto. - Antes de borrar, valida ruta y tipo de recurso.
- Genera informes o logs de tareas automáticas de sistema de archivos.
🧪 Ejercicios prácticos – Operación Cartógrafo
El equipo de mantenimiento necesita ordenar el sistema de archivos del proyecto: localizar backups, normalizar carpetas y generar informes automáticos.
Dispones de estos recursos: 👉 Descárgalos aquí
proyecto_sentinel/-> estructura base con archivos mezcladosproyecto_sentinel/logs/-> logs del sistemaproyecto_sentinel/backups/-> copias antiguas
🟢 Fase 1 – Exploración del árbol
🟩 Ejercicio 1 – Inventario inicial de rutas
Recorre proyecto_sentinel y muestra:
- Número total de archivos.
- Número total de carpetas.
- 3 rutas de ejemplo encontradas.
Objetivo: practicar recorrido y conteo.
🟦 Ejercicio 2 – Filtrado por extensión
Encuentra todos los archivos .log y .bak.
Muestra recuento por tipo.
Objetivo: dominar glob y rglob.
🟡 Fase 2 – Normalización de estructura
🟨 Ejercicio 3 – Crear carpeta de salida
Crea proyecto_sentinel/salidas si no existe.
Dentro, crea:
informe_logs.txtinforme_backups.txt
Objetivo: consolidar creación segura de rutas y archivos.
🟧 Ejercicio 4 – Informe de logs
Genera informe_logs.txt con:
- Total de
.logencontrados. - Rutas relativas de cada log.
Objetivo: automatizar inspección de contenido del árbol.
🔵 Fase 3 – Operaciones sobre archivos
🟥 Ejercicio 5 – Renombrado controlado
Renombra error_old.log a error_legacy.log dentro de logs.
Si no existe, informa por pantalla sin romper el programa.
Objetivo: manejo seguro de operaciones de cambio de nombre.
🟫 Ejercicio 6 – Limpieza de backups temporales
Detecta archivos *.tmp.bak y elimínalos.
Al final, muestra cuántos eliminaste.
Objetivo: aplicar limpieza con validación previa.
🔴 Fase Final – Entrega técnica
🟪 Ejercicio 7 – Informe consolidado (resumen_fs.txt)
Genera un informe final en salidas/resumen_fs.txt con:
- Total de carpetas.
- Total de archivos.
- Total de
.log. - Total de
.bak. - Total de temporales eliminados.
Formato sugerido:
Carpetas: X
Archivos: X
Logs: X
Backups: X
Temporales eliminados: X